package com.fengmi.pay.service;

import com.api.order.OrderApi;
import com.fengmi.order.entity.OmsOrder;
import com.fengmi.pay.config.WXConfig;
import com.fengmi.pay.websocket.WebsocketServer;
import com.fengmi.vo.ResultVO;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@RefreshScope
public class WXPayService implements IPayService {

    @Autowired
    private OrderApi orderApi;


    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Value("${pay.notify_url}")
    private String NOTIFYURL;
    @Override
    public ResultVO pay(String ordersn) {

        //1:查询订单信息
        OmsOrder order = orderApi.findOrderInfoByOrdersn(ordersn);

        if (order == null) {
            return new ResultVO(false,"没有该订单，支付失败");
        }

        if(order.getItemList() ==null || order.getItemList().size()<=0){
            return new ResultVO(false,"没有该订单，支付失败");
        }

        double money = order.getTotalAmount().doubleValue();

        int fee = (int)(money*100);

        String codeUrl = unifiedorder(ordersn, fee, NOTIFYURL);
        if (StringUtils.isEmpty(codeUrl)) {
            return new ResultVO(false,"支付失败");
        }


        //发送延时消息
        SendResult sendResult = rocketMQTemplate.syncSend("pay-delay:pay-delay-tag", MessageBuilder.withPayload(ordersn).build(), 2000, 3);

        if(sendResult.getSendStatus() == SendStatus.SEND_OK){ //发送成功
            return new ResultVO(true,"success",codeUrl);
        }else{
            //关闭订单
            closeorder(ordersn);
            return new ResultVO(false,"fail");
        }
    }

    @Override
    public ResultVO notify(String resxml) throws Exception {

        //验签
        //对xml进行解析 map
        Map<String,String> map = WXPayUtil.xmlToMap(resxml);
        //验证签名
        boolean signatureValid = WXPayUtil.isSignatureValid(map,
                new WXConfig().getKey());
        if(!signatureValid){ //验证签名不成功

            return  new ResultVO(false,"验签失败");
        }


        //获取订单号
        String out_trade_no = map.get("out_trade_no");

        //在微信支付系统查询订单状态
        String orderStatus = queryStatus(out_trade_no);
        if ("SUCCESS".equals(orderStatus)){//订单支付成功
            //todo: 校验微信实际付款金额和 业务库的付款金额一致

            //修改订单状态
            ResultVO updateRes = orderApi.update(out_trade_no);



            //通知客户端
            WebsocketServer.sendMsgToClient(out_trade_no,"paysuccess");

            return updateRes;

        }


        return new ResultVO(false,"fail");
    }


    //统一下单
    private  String unifiedorder(String ordersn,Integer fee ,String notifyUrl){

        try {
            WXConfig wxConfig = new WXConfig();

            //1：指定请求参数
            Map requestParamMap = new HashMap();
            requestParamMap.put("appid",wxConfig.getAppID());
            requestParamMap.put("mch_id",wxConfig.getMchID());
            requestParamMap.put("nonce_str", WXPayUtil.generateNonceStr());
            requestParamMap.put("body","下单");
            requestParamMap.put("out_trade_no",ordersn);
            requestParamMap.put("total_fee",fee+"");
            requestParamMap.put("spbill_create_ip","127.0.0.1");
            requestParamMap.put("notify_url",notifyUrl);
            requestParamMap.put("trade_type","NATIVE");

            //2：max转xml格式
            String requestParamXML = WXPayUtil.generateSignedXml(requestParamMap, wxConfig.getKey());


            //3:发送请求
            WXPayRequest request = new WXPayRequest(wxConfig);
            String responseXML = request.requestWithoutCert("/pay/unifiedorder", UUID.randomUUID().toString(), requestParamXML, false);


            //4:responseXML转成map
            Map<String, String> responseMap = WXPayUtil.xmlToMap(responseXML);


            //5:获取响应结果
            System.out.println(responseXML);
            System.out.println( responseMap.get("code_url"));

            return responseMap.get("code_url");

        } catch (Exception exception) {
            exception.printStackTrace();

            return  "";
        }


    }



    //查询订单状态
    public   String queryStatus(String ordersn)  {
        Map<String, String> resMap = null;


        try {
            //1:构建配置对象
            WXConfig config = new WXConfig();
            //2:封装请求参数
            Map params = new HashMap();
            params.put("appid",config.getAppID());
            params.put("mch_id",config.getMchID());
            params.put("out_trade_no",ordersn);
            params.put("nonce_str",WXPayUtil.generateNonceStr());
            //3:map转xml
            String requestXML = WXPayUtil.generateSignedXml(params, config.getKey());
            //4:发送请求WXPayRequest request = new WXPayRequest(config);
            WXPayRequest request = new WXPayRequest(config);
            String resXml = request.requestWithoutCert("/pay/orderquery", UUID.randomUUID().toString(),
                    requestXML, false);

            System.out.println(resXml);

            //5:响应结果转map集合
            resMap = WXPayUtil.xmlToMap(resXml);
            //6:获取支付状态
            System.out.println(resMap.get("trade_state"));
        } catch (Exception exception) {
            exception.printStackTrace();

            return "";
        }


        return resMap.get("trade_state");

    }


    public String  closeorder(String orderId) {
        Map<String, String> resMap = null;
        try {
            //1:构建配置对象
            WXConfig config = new WXConfig();
//2:封装请求参数
            Map params = new HashMap();
            params.put("appid",config.getAppID());
            params.put("mch_id",config.getMchID());
            params.put("out_trade_no", orderId);
            params.put("nonce_str",WXPayUtil.generateNonceStr());
//3:map转xml
            String reqeustXML = WXPayUtil.generateSignedXml(params, config.getKey());
//4:发送请求WXPayRequest request = new WXPayRequest(config);
            WXPayRequest request = new WXPayRequest(config);
            String resXML = request.requestWithoutCert("/pay/closeorder", UUID.randomUUID().toString(),
                    reqeustXML, false);
//5:响应结果转map集合
            resMap = WXPayUtil.xmlToMap(resXML);
//6:获取关闭结果
            System.out.println(resMap.get("result_code"));
            System.out.println(resMap.get("result_msg"));
        } catch (Exception exception) {
            exception.printStackTrace();

            return  "";
        }


        return  resMap.get("result_code");

    }




}
